/*
 * @Author: EltonLi lijiaming@uavi-tech.com
 * @Date: 2024-03-29 16:20:58
 * @LastEditors: lvgrape lvgrape@outlook.com
 * @LastEditTime: 2024-05-15 14:21:58
 * @FilePath: \PREMIUM_RTThread_V1.0\drivers\common\include\drv_soft_spi.h
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#ifndef __SOFT_SPI
#define __SOFT_SPI
#include <rtthread.h>
#include <drivers/spi.h>
#include "drv_common.h"
#include "spi-bit-ops.h"

struct at32_soft_spi_config
{
    rt_uint8_t clk;
    rt_uint8_t miso;
    rt_uint8_t mosi;
    const char *bus_name;
};
/* at32 sspi dirver class */
struct at32_sspi
{
    // struct rt_spi_bus bus;
    // struct rt_spi_bit_ops *ops;
    // struct rt_spi_configuration config;

    struct rt_spi_bus spi_bus;
    struct rt_spi_configuration config;
    struct rt_spi_bit_ops ops;
};

#ifdef BSP_USING_SSPI
#define SSPI_BUS_CONFIG            \
    {                              \
        .clk = BSP_SSPI_CLK_PIN,   \
        .miso = BSP_SSPI_MISO_PIN, \
        .mosi = BSP_SSPI_MOSI_PIN, \
        .bus_name = "sspi",        \
    }
#endif
struct io_poSOFT
{
    gpio_type *port;
    uint16_t pin;
};
typedef struct soft_spi_ios
{
    struct io_poSOFT cs;
    struct io_poSOFT clk;
    struct io_poSOFT mosi;
    struct io_poSOFT miso;
} soft_spi_ios_t;

struct soft_spi_bus_ops;

typedef struct soft_spi_bus
{
    struct soft_spi_ios *ios;
    uint8_t mode;
    uint32_t clktk;
    void (*delay_us)(uint8_t us);
    struct soft_spi_bus_ops *ops; // NOTE 先引用后声明的只能用指针
} soft_spi_bus_t;

struct soft_spi_bus_ops
{
    uint8_t (*transfer)(soft_spi_bus_t *bus, uint8_t data);
    void (*send_then_send)(soft_spi_bus_t *bus, uint8_t *sbuf1, uint8_t slen1, uint8_t *sbuf2, uint8_t slen2);
    void (*send_then_receive)(soft_spi_bus_t *bus, uint8_t *sbuf, uint8_t slen, uint8_t *rbuf, uint8_t rlen);
};
#define SOFT_SPI_CPHA (1 << 0)                          /* bit[0]:CPHA, clock phase */
#define SOFT_SPI_CPOL (1 << 1)                          /* bit[1]:CPOL, clock polarity */
#define SOFT_SPI_LSB (0 << 2)                           /* bit[2]: 0-LSB */
#define SOFT_SPI_MSB (1 << 2)                           /* bit[2]: 1-MSB */
#define SOFT_SPI_MODE_0 (0 | 0)                         /* CPOL = 0, CPHA = 0 */
#define SOFT_SPI_MODE_1 (0 | SOFT_SPI_CPHA)             /* CPOL = 0, CPHA = 1 */
#define SOFT_SPI_MODE_2 (SOFT_SPI_CPOL | 0)             /* CPOL = 1, CPHA = 0 */
#define SOFT_SPI_MODE_3 (SOFT_SPI_CPOL | SOFT_SPI_CPHA) /* CPOL = 1, CPHA = 1 */
void soft_spi_bus_init(struct soft_spi_bus *bus, struct soft_spi_ios *ios);
void soft_spi_bus_send_then_send(struct soft_spi_bus *bus, uint8_t *sbuf1, uint8_t slen1, uint8_t *sbuf2, uint8_t slen2);
void soft_spi_bus_send_then_receive(struct soft_spi_bus *bus, uint8_t *sbuf, uint8_t slen, uint8_t *rbuf, uint8_t rlen);
rt_err_t rt_sf_spi_device_attach(const char *bus_name, const char *device_name, rt_base_t pinnum);


#endif